#include <libshms/Thread.h>
#include <libshms/Mutex.h>
#include <libshms/StringUtil.h>
#include <ext/hash_map>
#include <iostream>

using namespace SHMS;

#define DIV_NUM 6

typedef  struct _tag_MutexMap{
	RWMutex lock;
}MutexMap;


class TestClass{
public:
	TestClass(){
		mMutexMap = new MutexMap[DIV_NUM];
	}
	void add(const std::string & groupId){
		int index = __gnu_cxx::hash<char*>()(groupId.c_str()) % DIV_NUM;
		WLock lock(mMutexMap[index].lock);
		groupMap[groupId] += 1;
	}
	void printTotal(){
		std::map<std::string, int>::iterator it = groupMap.begin();
		int total = 0;
		for (; it != groupMap.end(); ++it){
			total += it->second;
		}
		std::cout << "total is " << total << std::endl;
	}
private:
	std::map<std::string, int> groupMap;
	MutexMap * mMutexMap;
};

class TestThread: public Thread{
	public:
		TestThread(TestClass & _testClass):testClass(_testClass){
			mMutexMap = new MutexMap[DIV_NUM];
		}

		void thread(){
			for(int i = 0; i < 100; ++i){
				std::string groupId = toString(i);
				testClass.add(groupId);
			}
		}
	private:
		TestClass & testClass;
		MutexMap * mMutexMap;
};

int main(){
	TestClass testClass;
	TestThread ** thread;
	const int threadCount = 100;
	thread = new TestThread*[threadCount];
	for (int i = 0; i < threadCount; ++i){
		thread[i] = new TestThread(testClass);
		thread[i]->start();
	}
	for (int i = 0; i < threadCount; ++i){
		thread[i]->join();
	}
	for (int i = 0; i < threadCount; ++i){
		delete thread[i];
	}
	delete thread;
	testClass.printTotal();
	return 0;
}
